<?php
class fs_form extends CI_Model {

    var $_id = 0;
    var $_table = "";
    var $_db = "";
    var $_reserved_prefixes = array();
    

    /* Textual */
    var $title_new = "Creat new";
    var $title_edit = "Editing";

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();

        $this->load->model("fs_tables");
    }

    function build_form($table, $id)
    {
        /* Set vars */
        $this->_id = $id;
        $this->_table = $table;
        $this->_db = $this->session->userdata('active_site');

        /* Set sessions */
        $this->session->set_userdata( array('form_post_table' => $table, 'form_post_id' => $id) );
        
        /* Form post url */
        $form_post_url = "site/save/";

        /* Build form */
        $start =    "<form id='fs_form' method='post' action='".$form_post_url."' class='bootstrap'>";
        $start .=   "<fieldset>";
        $start .=   ($id == 0) ? "<legend>" . $this->title_new . " " . $table . "</legend>" : "<legend>" . $this->title_edit . " " . $table . ": " . $id . "</legend>";

        // Elements from DB
        $content = $this->get_elements();

        // Actions (buttons for saving)
        $action = $this->form_actions();

        $end =      "</fieldset>";
        $end .=     "</form>";


        // Complete form
        $form = $start . $content . $action . $end;

        return $form;
    }

    private function form_actions($save_btn_txt = "Save Changes", $reset_btn_txt = "Cancel") {
        $html = "<div class='actions'>
                    <button type='submit' id='btnSubmitFS' class='btn primary'>".$save_btn_txt."</button>&nbsp;<button type='reset' class='btn'>".$reset_btn_txt."</button>
                 </div>";

        return $html;
    }

    private function get_elements()
    {
        // Get fields from database
        $query = $this->db->query("SHOW FULL COLUMNS FROM " . $this->db->escape_str($this->_table) . " FROM " . $this->_db);
        $fields = $query->result_array();

        // Get record data from database
        $dbtmp = $this->fs_tables->select_single_db();
        $query = $dbtmp->query("SELECT * FROM " . $this->db->escape_str($this->_table) . " WHERE id = ?", array($this->_id));
        $records = $this->array_to_numeric( $query->result_array() );
        $record_counter = 0;

        
        // Prepare result
        $result = "";

        // Loop through fields and record
        foreach ($fields as $form_field)
        {
            // Type comes with maxlength, lets extract
            $field_type = (strpos($form_field["Type"], "(") > 0) ? substr($form_field["Type"], 0, strpos($form_field["Type"],"(") ) : $form_field["Type"];
            $field_maxlength =  ( strpos($form_field["Type"], "(") > 0) ? substr( $form_field["Type"], strpos($form_field["Type"], "(")+1, strlen($form_field["Type"]) ) : "";
            $field_maxlength = str_replace(")", "", $field_maxlength);
            $value = $records[$record_counter];


            // Load control according to type
            switch ($field_type) {
                case "int":
                    $result .= $this->field_int($form_field, $field_type, $field_maxlength, $value);
                    break;
                case "tinyint":
                    $result .= $this->field_boolean($form_field, $field_type, $field_maxlength, $value);
                        break;
                case "varchar":
                case "year":
                case "decimal":
                case "float":
                case "double":
                    $result .= $this->field_varchar($form_field, $field_type, $field_maxlength, $value);
                    break;
                case "datetime":
                case "timestamp":
                    $result .= $this->field_datetime($form_field, $field_type, $field_maxlength, $value);
                    break;
                case "date":
                    $result .= $this->field_date($form_field, $field_type, $field_maxlength, $value);
                    break;
                case "text":
                case "longtext":
                    $result .= $this->field_text($form_field, $field_type, $field_maxlength, $value);
                    break;
            }

            $record_counter++;
        }

        // Last but not least, allways add the id to the form
        $result .= "<input type='hidden' name='fs_unique_id' value='".$this->_id."' />";

        return $result;
    }
    

    // Convert array from text keys to numeric keys
    private function array_to_numeric($array)
    {
        $i=0;
        foreach($array[0] as $item) {
            $result[$i] = $item;
            $i++;
        }
        return $result;
    }


    /*************************************************/
    /******************* FIELD TYPES *****************/
    /*************************************************/


    // Int
    private function field_int($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);
        

        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <input class='small ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$field_name."' size='".$length."' value='".$value."' type='text'>
                        ".$field_help["inline"]."
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }

    // Int
    private function field_boolean($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);

        // Custom checked prop
        $checked = ($value == 1) ? "checked='checked'" : "";


        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label id='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <ul class='inputs-list'><li>
                            <label for='".$field_id."'>
                                <input ". $checked ." id='".$field_id."' class='".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." type='checkbox' name='".$field_name."'/>
                                <span>".$field_comment['help']."</span>
                            </label>
                        </li></ul>
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }

    // Varchar
    private function field_varchar($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);


        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <input class='xlarge ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$field_name."' size='".$length."' value='".$value."' type='text'>
                        ".$field_help["inline"]."
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }

    // Textarea
    private function field_text($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);


        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <textarea rows='11' class='xxlarge ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$field_name."'>".$value."</textarea>
                        ".$field_help["block"]."
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }

    // Date _AND_ time
    private function field_datetime($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);

        // Custom values to split up the date and the time field
        $value = strtotime($value);
        $date_format = $this->config->item("firestone_date_format");
        $time_format = $this->config->item("firestone_time_format");

        $date_value = (empty($value)) ? date($date_format) :  date($date_format, $value);
        $time_value = (empty($value)) ? date($time_format) :  date($time_format, $value);

        $date_length = strlen($date_value);
        $time_length = strlen($time_value);

        $date_name = $field["Field"]."_fs_split_date";
        $time_name = $field["Field"]."_fs_split_time";


        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <div class='inline-inputs'>
                            <input class='small ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$date_name."' size='".$date_length."' value='".$date_value."' type='text'>
                            <input class='mini ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." type='text' name='".$time_name."' size='".$time_length."' value='".$time_value."'/>
                        </div>
                        ".$field_help["inline"]."
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }

    // Only a date
    private function field_date($field, $type, $length, $value)
    {
        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special = $this->is_special($field, $type, $length, $value);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);

        // Convert to config date
        $date_format = $this->config->item("firestone_date_format");
        $value = date($date_format, strtotime($value));


        if($field_special == false)
        {
            /* HTML result */
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <input class='medium ".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$field_name."' size='".$length."' value='".$value."' type='text'>
                        ".$field_help["inline"]."
                      </div>
                    </div>";
        } else {
            $html = $field_special['special'];
        }

        return $html;
    }



    /*************************************************/
    /****************SPECIAL PROPERTIES **************/
    /*************************************************/

    // Check to see if there is a special property applied to the field
    private function special_properties($field,$type,$length)
    {
        $result = "";

        // Load control according to type
        switch ($type) {
            case "int":
                $result = $this->property_int($field,$type,$length);
                break;
            case "year":
                $result = $this->property_year($field,$type,$length);
                break;
            case "decimal":
                $result = $this->property_decimal($field,$type,$length);
                break;
            case "float":
                $result = $this->property_float($field,$type,$length);
                break;
            case "double":
                $result = $this->property_double($field,$type,$length);
                break;
        }

        return $result;
    }
    

    // Special properties for an int field
    private function property_int($field,$type,$length)
    {
        $result = array();

        // Autoincrement (id field)
        if($field["Extra"] == "auto_increment") {
            $result['attribute'] = "disabled='disabled'";
            $result['css-class'] = "disabled";
        }

        return $result;
    }

    // Special properties for an year field
    private function property_year($field,$type,$length)
    {
        $result = array();
        $result['attribute'] = "style='width:60px;'";
        $result['css-class'] = "";

        return $result;
    }

    // Special properties for an decimal field
    private function property_decimal($field,$type,$length)
    {
        $result = array();
        $result['attribute'] = "style='width:100px;'";
        $result['css-class'] = "";

        return $result;
    }

    // Special properties for an float field
    private function property_float($field,$type,$length)
    {
        $result = array();
        $result['attribute'] = "style='width:100px;'";
        $result['css-class'] = "";

        return $result;
    }

    // Special properties for an double field
    private function property_double($field,$type,$length)
    {
        $result = array();
        $result['attribute'] = "style='width:100px;'";
        $result['css-class'] = "";

        return $result;
    }


    /*************************************************/
    /**************** SPECIAL COMMENTS ***************/
    /*************************************************/

    // Check to see if there is a special comment applied to the field
    private function special_comment($field,$type,$length)
    {
        if( empty($field["Comment"]) ) {
           return "";
        } else {
            // Extract comment-tags from comment
            $tags = explode("|", $field["Comment"]);
            $result = array();

            // Loop through all comments
            foreach($tags as $tag)  {
               $key = strtolower( substr($tag, 0, strpos($tag,"=") ) );
               $value = substr($tag, strpos($tag, "=")+1, strlen($tag) );
               $result[$key] = $value;
            }

            return $result;
        }
    }


    /*************************************************/
    /***************** SPECIAL FIELDS ****************/
    /*************************************************/

    // Check to see if there is a rule applied to the field
    private function is_special($field,$type,$length,$value)
    {
        // Get prefix
        $prefix = (strpos($field["Field"], "_") > 0) ? substr($field["Field"], 0, strpos($field["Field"], "_") ) : "";

        // Values from another table in a listbox
        if ($type == "int" && $prefix == "list") {
            array_push($this->_reserved_prefixes, "list_");
            return array("special" => $this->get_listbox($field,$type,$length,$value) );
        }


        
        else {
            return false;
        }
    }

    // Listbox
    private function get_listbox($field,$type,$length,$value,$default_option = "Select an option") {
        // Parse parameters
        $dest_table = str_replace("list_", "", $field["Field"]);

        /* Standard values */
        $field_id = $field["Field"] . "_" . $this->_id;
        $field_name = $field["Field"];
        $field_label = $this->format_label($field["Field"]);
        $field_special_properties = $this->special_properties($field, $type, $length);
        $field_comment = $this->special_comment($field, $type, $length);
        $field_help = $this->format_help($field_comment['help']);

        // Check if table exists
        $dbtmp = $this->fs_tables->select_single_db();


        if($dbtmp->table_exists($dest_table))
        {
            // Query
            $char_field = $this->fs_tables->get_field_by_type($dest_table, "string");
            $ident_field = $this->fs_tables->get_field_by_type($dest_table, "int");
            $query = $dbtmp->query("SELECT * FROM " . $this->db->escape_str($dest_table) . " ORDER BY " . $char_field . " ASC");

            // Build HTML
            $html = $this->format_legend($field_comment['legend']) .
                    "<div class='clearfix'>
                      <label for='".$field_id."'>".$field_label."</label>
                      <div class='input'>
                        <select class='".$field_special_properties['css-class']."' ".$field_special_properties['attribute']." id='".$field_id."' name='".$field_name."'>
                            <option value='0'>".$default_option."</option>";

                            // Loop through records
                            foreach($query->result_array() as $row) {
                               $html .= ($row[$ident_field] == $value) ? "<option value='".$row[$ident_field]."' selected='selected'>" . $row[$char_field] . "</option>" : "<option value='".$row[$ident_field]."'>" . $row[$char_field] . "</option>";
                            }
                            
            $html .=    "</select>
                        ".$field_help["inline"]."
                      </div>
                    </div>";
        } else {
            return false;
        }

        return $html;
    }



    /*************************************************/
    /************** FORMATTING FUNCTIONS *************/
    /*************************************************/
    private function format_help($txt) {
        if(empty($txt)) {
            return "";
        } else {
            return array("block" => "<span class='help-block'>".$txt."</span>",
                         "inline" => "<span class='help-inline'>".$txt."</span>");
        }
    }

    private function format_legend($txt) {
        if(empty($txt)) {
            return "";
        } else {
            return  "</fieldset>
                     <fieldset>
                        <legend>" . $txt . "</legend>";
        }
    }

    // Remove garbish from labels
    private function format_label($text) {
        $result = $text;

        // Format text
        $result = str_replace($this->_reserved_prefixes, "", $result);
        $result = str_replace("_", " ", $result);

        return $result;
    }

}